#include <bits/stdc++.h>
#define rep(i,a,b) for (int i = a; i <= b; ++ i)
#define per(i,a,b) for (int i = a; i >= b; -- i)
#define ll long long
#define INF 0x3f3f3f3f
#define llINF 0x3f3f3f3f3f3f3f3f

using namespace std;

namespace Source {
	template<typename T>
	inline T input() {
		T x = 0, f = 1;
		char c = getchar();
		while (c < '0' || c > '9') {
			if (c == '-') f = -1;
			c = getchar();
		}
		while (c <= '9' && c >= '0') {
			x = (x << 3) + (x << 1) + (c ^ 48);
			c = getchar();
		}
		return x * f;
	}

	template<int mod>
	int quickPow(int a, int b) {
		int res = 1;
		while (b) {
			if (b & 1) res = 1LL * res * a % mod;
			a = 1LL * a * a % mod;
			b >>= 1;
		}
		return res;
	}

	template<int mod>
	struct mint {
		int x;

		mint() {  }

		mint(int a) { if (a >= mod) x = a % mod;else if (a < 0) x = a + mod;else x = a; }

		mint operator + (mint b) {
			mint c = x;
			c.x += b.x;
			if (c.x >= mod) c.x -= mod;
			return c;
		}

		void operator += (mint b) { *this = *this + b; }

		mint operator * (mint b) {
			mint c = x;
			c.x = 1LL * c.x * b.x % mod;
			return c;
		}

		void operator *= (mint b) { *this = *this * b; }

		mint operator - (mint b) {
			mint c = x;
			c.x -= b.x;
			if (c.x < 0) c.x += mod;
			return c;
		}

		void operator -= (mint b) { *this = *this - b; }
	};

	template<typename T>
	struct Frac {
		T a, b;

		Frac() {  }

		Frac(T x) { a = x, b = 1; }

		Frac(T x, T y) : a(x), b(y) {  }

		void reduct() {
			T d = __gcd(a, b);
			a /= d;
			b /= d;
		}

		Frac operator + (Frac y) {
			Frac c;
			c.b = b * y.b;
			c.a = a * y.b + b * y.a;
			c.reduct();
			return c;
		}

		void operator += (Frac y) { *this = *this + y; }

		Frac operator * (Frac y) {
			Frac c;
			c.a = a * y.a;
			c.b = b * y.b;
			c.reduct();
			return c;
		}

		void operator *= (Frac y) { *this = *this * y; }

		Frac operator - (Frac y) {
			y.a = -y.a;
			return *this + y;
		}

		void operator -= (Frac y) { *this = *this - y; }

		Frac operator / (Frac y) {
			swap(y.a, y.b);
			return *this * y;
		}

		void operator /= (Frac y) { *this = *this / y; }

		bool operator < (Frac y) const { return a * y.b < b * y.a; }

		bool operator > (Frac y) const { return y < *this; }

		bool operator != (Frac y) const { return *this < y || *this > y; }

		bool operator == (Frac y) const { return !(*this != y); }

		bool operator <= (Frac y) const { return !(*this > y); }

		bool operator >= (Frac y) const { return !(*this < y); }
	};

	template<typename T, int n>
	struct Matrix {
		T a[n][n];

		T* operator [] (int x) { return a[x]; }

		Matrix(int x = 0) {
			rep (i,1,n) rep (j,1,n) a[i - 1][j - 1] = 0;
			if (x == 1) rep (i,0,n - 1) a[i][i] = 1;
			else if (x == 2) {
				a[0][0] = 1, a[0][1] = 0, a[0][2] = 0;
				a[1][0] = 1, a[1][1] = 1, a[1][2] = 0;
				a[2][0] = 1, a[2][1] = 0, a[2][2] = 1;
			}
			else if (x == 3) {
				a[0][0] = 1, a[0][1] = 1, a[0][2] = 0;
				a[1][0] = 0, a[1][1] = 1, a[1][2] = 0;
				a[2][0] = 0, a[2][1] = 1, a[2][2] = 1;
			} else if (x == 4) { a[0][2] = 1; }
		}

		Matrix operator * (Matrix b) {
			Matrix c;
			rep (i,0,n - 1) rep (j,0,n - 1) rep (k,0,n - 1) c[i][j] += a[i][k] * b[k][j];
			return c;
		}

		void operator *= (Matrix b) { *this = *this * b; }

		Matrix operator + (Matrix b) {
			Matrix c;
			rep (i,1,n) rep (j,1,n) c[i][j] = a[i][j] + b[i][j];
			return c;
		}

		void operator += (Matrix b) { *this = *this + b; }

		Matrix operator ^ (int b) {
			Matrix c(1), a = *this;
			while (b) {
				if (b & 1) c *= a;
				a *= a;
				b >>= 1;
			}
			return c;
		}

		Matrix operator ^ (ll b) {
			Matrix c(1);
			while (b) {
				if (b & 1) c *= a;
				a *= a;
				b >>= 1;
			}
			return c;
		}

		void print() {
			rep (i,0,n - 1) rep (j,0,n - 1) cerr << a[i][j].x << " \n"[j == n - 1];
		}
	};
}

int n, k[500010], c, cnt = 0, val[1000010], maxv, cntl, vall[1000010], maxl;
ll b[500010];
vector<int> a[500010];
tuple<int, int, int> d[1000010];
vector< pair<int, int> > mrge[1000010];

struct segmentTree {
	int tree[1000010];
	ll sum;
	
	void update(int x, int k) {
		sum += b[tree[x] + k] - b[tree[x]];
		tree[x] += k;
	}
	
	ll query() { return sum; }
}tree;

struct segmentTree2 {
	int sumSz;
	ll sum;
	
	void exLength(int k) { sum += 1LL * sumSz * k; }
	
	void update() {
		-- sumSz;
		-- sum;
	}
	
	void create() { rep (i,1,n) sumSz += k[i]; }
	
	ll query() { return sum; }
}tree2;

int main() {
	freopen("list.in", "r", stdin);
	freopen("list.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> n;
	rep (i,1,n) {
		cin >> k[i];
		a[i].resize(k[i] + 1);
		rep (j,1,k[i]) cin >> a[i][j], d[++ cnt] = make_tuple(a[i][j], i, j);
	}
	cin >> c;
	rep (i,1,n) cin >> b[i];
	rep (i,1,n) b[i] *= i;
	sort(d + 1, d + cnt + 1);
	rep (i,1,cnt) {
		if (get<0>(d[i]) != get<0>(d[i - 1])) val[++ maxv] = get<0>(d[i]);
		a[get<1>(d[i])][get<2>(d[i])] = maxv;
	}
	rep (i,1,n) rep (j,1,k[i]) tree.update(a[i][j], 1);
	rep (i,1,n) rep (j,2,k[i]) d[++ cntl] = make_tuple(val[a[i][j]] - val[a[i][j - 1]] + 1, i, j);
	sort(d + 1, d + cntl + 1);
	rep (i,1,cntl) {
		if (get<0>(d[i - 1]) != get<0>(d[i])) vall[++ maxl] = get<0>(d[i]);
		mrge[maxl].emplace_back(make_pair(get<1>(d[i]), get<2>(d[i])));
	}
	tree2.create();
	tree2.exLength(1);
	ll ans = tree.query() + tree2.query() * c;
	vector<int> id;
	vall[0] = 1;
	id.emplace_back(1);
	rep (i,1,maxl) {
		tree2.exLength(vall[i] - vall[i - 1]);
		for (auto [x, y] : mrge[i]) {
			tree2.update();
			tree.update(a[x][y], -1);
		}
		ll temp = tree.query() + tree2.query() * c;
		if (temp < ans) {
			ans = temp;
			vector<int>().swap(id);
			id.emplace_back(vall[i]);
		} else if (temp == ans) id.emplace_back(vall[i]);
	}
	cout << ans << ' ' << id.size() << endl;
	for (int x : id) cout << x << ' ';
	cout << endl;
	return 0;
}



